package com.fingard.dsp.bank.directbank.nnbill01;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.SendBankRespose;
import com.fingard.dsp.bank.directbank.bankInterface.ISMSRec;
import com.fingard.dsp.bank.reqrespobj.single.ReqQrySingle;
import com.fingard.dsp.bank.reqrespobj.single.RetAtsSingle;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.dsp.bank.reqrespobj.smsrec.ReqSMSRec;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;

import java.util.HashMap;

/**
 * 快钱快捷支付
 * 
 * @author Cruise
 * @date 2018年8月17日
 */
public class NNBill01SMSRec extends NNBill01Base implements ISMSRec {
	/**
	 * 快捷支付提交
	 * 
	 * 1、普通短信扣款流程:绑卡标志为空或者绑卡标志为0-非绑卡,传入全要素
	 *    1)获取验证码:
	 *    2)发送验证码扣款:
	 * 2、改进后短信扣款流程:
	 *    1)首次绑卡:绑卡标志为1,传入全要素
	 *        (1)获取验证码:
	 *        (2)发送验证码扣款:
	 *    2)再次支付:绑卡标志为0,UserId有值
	 *        (1)获取验证码:
	 *        (2)发送验证码扣款:
	 */
	@Override
	public RetAtsSingle d_9110_SMSRec(ReqSMSRec p_req9110) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req9110.reqHeader);
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
		tmpRetDetail.reqSeqID = p_req9110.singleDetail.askNumber;

		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req9110.singleDetail.recAct, "smsRec");
			if (actItem == null) {
				tmpRetDetail.respCode = "0";
				tmpRetDetail.respInfo = "未找到账号:[" + p_req9110.singleDetail.recAct + "]商户配置信息!";
				tmpRetDetail.reqSeqID = p_req9110.singleDetail.askNumber;
				tmpRetDetail.transState = PaymentState.FAIL_Payment;
				tmpRetDetail.payInfoCode = "E9981";
				retAts.writeRetDetail(tmpRetDetail);
				return retAts;
			}

			String submitUrl = "";
			StringBuilder sbXml = new StringBuilder();
			if ("01".equals(p_req9110.singleDetail.step)) {
				// 快捷支付手机动态鉴权（首次）
				sbXml.append("<?xml version=\"1.0\" encoding=\"" + getCharset() + "\" standalone=\"yes\"?>");
				sbXml.append("<MasMessage xmlns=\"http://www.99bill.com/mas_cnp_merchant_interface\">");
				sbXml.append("<version>1.0</version>");
				sbXml.append("<GetDynNumContent>");
				sbXml.append("<merchantId>" + actItem.merchantId + "</merchantId>");
				if (StringHelper.hasAnyChar(p_req9110.singleDetail.userId)) {
					sbXml.append("<customerId>" + p_req9110.singleDetail.userId + "</customerId>");
				}
				
				boolean isContinue = false;
				String isCardBind = p_req9110.singleDetail.isCardBind;
				if (StringHelper.hasAnyChar(p_req9110.singleDetail.userId) && "0".equals(isCardBind)) {
					isContinue = true;
				} 
				if (!isContinue) {
					if (StringHelper.hasAnyChar(p_req9110.singleDetail.payName)) {
						sbXml.append("<cardHolderName>" + p_req9110.singleDetail.payName + "</cardHolderName>");
					}
					if (StringHelper.hasAnyChar(p_req9110.singleDetail.certType)) {
						sbXml.append("<idType>" + this.convertCertTypeToBank(p_req9110.singleDetail.certType) + "</idType>");
					}
					if (StringHelper.hasAnyChar(p_req9110.singleDetail.certNum)) {
						sbXml.append("<cardHolderId>" + p_req9110.singleDetail.certNum + "</cardHolderId>");
					}
					if (StringHelper.hasAnyChar(p_req9110.singleDetail.payAct)) {
						sbXml.append("<pan>" + p_req9110.singleDetail.payAct + "</pan>");
					}
					if (StringHelper.hasAnyChar(p_req9110.singleDetail.cellPhone)) {
						sbXml.append("<phoneNO>" + p_req9110.singleDetail.cellPhone + "</phoneNO>");
					}
					if (p_req9110.singleDetail.cvv2.length() > 0 && p_req9110.singleDetail.expiredDate.length() > 0) {
						sbXml.append("<expiredDate>" + p_req9110.singleDetail.expiredDate + "</expiredDate>");
						sbXml.append("<cvv2>" + p_req9110.singleDetail.cvv2 + "</cvv2>");
					}
				}
				
				String[] findValues = new String[2];
				findValues[0] = p_req9110.singleDetail.payBankCode;
				findValues[1] = p_req9110.singleDetail.payAreaName;
				HashMap<String, String> BANK_CODE = this.getBankConfig().getMapAdvanceValues("BankCodeMapping",
						new String[] { "ATSBankCode", "ATSAreaName" }, new String[] { "value" }, findValues);
				if (BANK_CODE != null && BANK_CODE.size() > 0 && BANK_CODE.containsKey("value")) {
					sbXml.append("<bankId>" + BANK_CODE.get("value") + "</bankId>");
				} else {
					sbXml.append("<bankId>" + findValues[0] + "</bankId>");
				}
				if (StringHelper.hasAnyChar(p_req9110.singleDetail.shortCardNo)) {
					sbXml.append("<storablePan>" + p_req9110.singleDetail.shortCardNo + "</storablePan>");
				}
				sbXml.append("<amount>" + p_req9110.singleDetail.payAmount + "</amount>");
				sbXml.append("<externalRefNumber>" + p_req9110.singleDetail.askNumber + "</externalRefNumber>");
				sbXml.append("</GetDynNumContent>");
				sbXml.append("</MasMessage>");
				submitUrl = bankFront.getUrl("smsRecStep01");
			} else if ("02".equals(p_req9110.singleDetail.step)) {
				// 快捷支付消费
				sbXml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
				sbXml.append("<MasMessage xmlns=\"http://www.99bill.com/mas_cnp_merchant_interface\">");
				sbXml.append("<version>1.0</version>");
				sbXml.append("<TxnMsgContent>");
				sbXml.append("<interactiveStatus>TR1</interactiveStatus>");
				sbXml.append("<spFlag>QuickPay</spFlag>");
				sbXml.append("<txnType>PUR</txnType>");
				sbXml.append("<merchantId>" + actItem.merchantId + "</merchantId>");
				if (StringHelper.hasAnyChar(p_req9110.singleDetail.userId)) {
					sbXml.append("<customerId>" + p_req9110.singleDetail.userId + "</customerId>");
				}
				if (StringHelper.hasAnyChar(p_req9110.singleDetail.shortCardNo)) {
					sbXml.append("<storableCardNo>" + p_req9110.singleDetail.shortCardNo + "</storableCardNo>");
				}
				String[] findValues = new String[2];
				findValues[0] = p_req9110.singleDetail.payBankCode;
				findValues[1] = p_req9110.singleDetail.payAreaName;
				HashMap<String, String> BANK_CODE = this.getBankConfig().getMapAdvanceValues("BankCodeMapping",
						new String[] { "ATSBankCode", "ATSAreaName" }, new String[] { "value" }, findValues);
				if (BANK_CODE != null && BANK_CODE.size() > 0 && BANK_CODE.containsKey("value")) {
					sbXml.append("<bankId>" + BANK_CODE.get("value") + "</bankId>");
				} else {
					sbXml.append("<bankId>" + findValues[0] + "</bankId>");
				}
				
				boolean isContinue = false;
				String isCardBind = p_req9110.singleDetail.isCardBind;
				if (StringHelper.hasAnyChar(p_req9110.singleDetail.userId) && "0".equals(isCardBind)) {
					isContinue = true;
				} 
				if (!isContinue) {
					if (StringHelper.hasAnyChar(p_req9110.singleDetail.payAct)) {
						sbXml.append("<cardNo>" + p_req9110.singleDetail.payAct + "</cardNo>");
					}
					if (p_req9110.singleDetail.cvv2.length() > 0 && p_req9110.singleDetail.expiredDate.length() > 0) {
						sbXml.append("<expiredDate>" + p_req9110.singleDetail.expiredDate + "</expiredDate>");
						sbXml.append("<cvv2>" + p_req9110.singleDetail.cvv2 + "</cvv2>");
					}
					if (StringHelper.hasAnyChar(p_req9110.singleDetail.payName)) {
						sbXml.append("<cardHolderName>" + p_req9110.singleDetail.payName + "</cardHolderName>");
					}
					if (StringHelper.hasAnyChar(p_req9110.singleDetail.certType)) {
						sbXml.append("<idType>" + this.convertCertTypeToBank(p_req9110.singleDetail.certType) + "</idType>");
					}
					if (StringHelper.hasAnyChar(p_req9110.singleDetail.certNum)) {
						sbXml.append("<cardHolderId>" + p_req9110.singleDetail.certNum + "</cardHolderId>");
					}
				}
				
				sbXml.append("<terminalId>" + actItem.termId + "</terminalId>");
				sbXml.append("<externalRefNumber>" + p_req9110.singleDetail.askNumber + "</externalRefNumber>");
				sbXml.append("<entryTime>" + Format.DateTime14Format.format(p_req9110.singleDetail.getPayDateTime())+ "</entryTime>");
				sbXml.append("<amount>" + p_req9110.singleDetail.payAmount + "</amount>");
				sbXml.append("<tr3Url>" + bankFront.getUrl("smsRecNotify") + "</tr3Url>");
				sbXml.append("<extMap>");
				sbXml.append("<extDate><key>phone</key><value>" + p_req9110.singleDetail.cellPhone + "</value></extDate>");
				sbXml.append("<extDate><key>validCode</key><value>" + p_req9110.singleDetail.verifyCode	+ "</value></extDate>");
				
				String savePciFlag = "";
				String payBatch = "1";
				if ("1".equals(p_req9110.singleDetail.saveAuth)) {
					savePciFlag = "1";
				} else {
					savePciFlag = "0";
				}
				
				// 首次支付：customerId，savePciFlag=1，payBatch=1
				// 再次支付:savePciFlag=0、payBatch=2
				if (StringHelper.hasAnyChar(p_req9110.singleDetail.userId)) {
					if ("1".equals(isCardBind)) {//首次支付
						savePciFlag = "1";
						payBatch = "1";
					} else {
						savePciFlag = "0";
						payBatch = "2";
					}
				} 
				
				sbXml.append("<extDate><key>savePciFlag</key><value>" + savePciFlag + "</value></extDate>");
				sbXml.append("<extDate><key>token</key><value>" + p_req9110.singleDetail.token + "</value></extDate>");
				sbXml.append("<extDate><key>payBatch</key><value>" + payBatch + "</value></extDate>");
				sbXml.append("</extMap>");
				
				sbXml.append("</TxnMsgContent>");
				sbXml.append("</MasMessage>");
				submitUrl = bankFront.getUrl("smsRecStep02");
			} else {
				tmpRetDetail.respCode = "0";
				tmpRetDetail.respInfo = "未能识别的step：" + p_req9110.singleDetail.step;
				tmpRetDetail.reqSeqID = p_req9110.singleDetail.askNumber;
				tmpRetDetail.transState = PaymentState.FAIL_Payment;
				tmpRetDetail.payInfoCode = "E9981";
				retAts.writeRetDetail(tmpRetDetail);
				return retAts;
			}
			String reqXml = sbXml.toString();
			this.WriteBankLogStep2(reqXml);
			this.WriteBankLogLn("提交服务地址：" + submitUrl);
			SendBankRespose smsResp = SmsPost.sendPost(submitUrl, actItem, reqXml, getCharset());
			this.WriteBankLogStep3(smsResp);

			if (smsResp.connState.length() == 0) {
				if (smsResp.retMessage.indexOf("<") >= 0) {
					XmlTextReader xmlReader = new XmlTextReader(smsResp.retMessage);
					tmpRetDetail.respCode = "0";

					if (p_req9110.singleDetail.step.equals("01")) {// 第一步，发短信
						String responseCode = xmlReader.getFirstText("/MasMessage/GetDynNumContent/responseCode");
						tmpRetDetail.payInfoCode = responseCode;
						tmpRetDetail.reqSeqID = p_req9110.singleDetail.askNumber;
						if (responseCode != null && responseCode.equals("00")) {
							tmpRetDetail.respInfo = "已提交";
							tmpRetDetail.transState = PaymentState.SUCCESS;
							tmpRetDetail.token = xmlReader.getFirstText("/MasMessage/GetDynNumContent/token");
						} else {
							if (StringHelper.hasAnyChar(responseCode)) {
								tmpRetDetail.transState = PaymentState.FAIL;
							} else {
								tmpRetDetail.transState = PaymentState.EXCEPTION;
							}
							tmpRetDetail.respInfo = xmlReader
									.getFirstText("/MasMessage/GetDynNumContent/responseTextMessage");
						}
					} else {// 第二步
                        int countTxnMsgCo = xmlReader.countElement("/MasMessage/TxnMsgContent");
                        if (countTxnMsgCo > 0) {
                            String interactiveStatus = xmlReader.getFirstText("/MasMessage/TxnMsgContent/interactiveStatus");
                            if ("TR2".equals(interactiveStatus)) {
                                String responseCode = xmlReader.getFirstText("/MasMessage/TxnMsgContent/responseCode");
                                tmpRetDetail.payInfoCode = responseCode;
                                tmpRetDetail.reqSeqID = xmlReader
                                        .getFirstText("/MasMessage/TxnMsgContent/externalRefNumber");
                                if (StringHelper.isNullOrEmpty(tmpRetDetail.reqSeqID)) {
                                    tmpRetDetail.reqSeqID = p_req9110.singleDetail.askNumber;
                                }
                                tmpRetDetail.transAmt = xmlReader.getFirstText("/MasMessage/TxnMsgContent/amount");
                                tmpRetDetail.transState = responseCode;
                                tmpRetDetail.respInfo = xmlReader
                                        .getFirstText("/MasMessage/TxnMsgContent/responseTextMessage");

                                tmpRetDetail.outTransID = xmlReader.getFirstText("/MasMessage/TxnMsgContent/refNumber");
                            } else {
                                tmpRetDetail.respCode = "-1";
                                tmpRetDetail.respInfo = "返回的interactiveStatus:" + interactiveStatus + "不符合预期";
                            }
                        } else if (countTxnMsgCo == 0) {
                            tmpRetDetail.transState = xmlReader.getFirstText("/MasMessage/ErrorMsgContent/errorCode");
                            tmpRetDetail.payInfoCode = xmlReader.getFirstText("/MasMessage/ErrorMsgContent/errorMessage");
                            tmpRetDetail.respInfo = xmlReader.getFirstText("/MasMessage/ErrorMsgContent/errorMessage");
                        } else {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = "返回报文结构不符合预期";
                        }
					}
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = smsResp.retMessage;
				}
			} else if (smsResp.connState.equals(FailCode.E9999) || smsResp.connState.equals(FailCode.E9981)) {
				tmpRetDetail.respCode = "0";
				tmpRetDetail.respInfo = smsResp.retMessage;
				tmpRetDetail.reqSeqID = p_req9110.singleDetail.askNumber;
				if (p_req9110.singleDetail.step.equals("01")) {
					tmpRetDetail.transState = PaymentState.FAIL;
				} else {
					tmpRetDetail.transState = PaymentState.FAIL_Payment;
				}
				tmpRetDetail.payInfoCode = smsResp.connState;
			} else {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = smsResp.retMessage;
			}
		} catch (Exception ex) {
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = ex.getMessage();
			tmpRetDetail.reqSeqID = p_req9110.singleDetail.askNumber;
			this.WriteBankLogLn(ex);
		}
		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

	/**
	 * 快捷支付状态查询
	 */
	@Override
	public RetAtsSingle d_9146_QrySMSRec(ReqQrySingle p_req9146) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req9146.reqHeader);
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();
		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req9146.recAct, "smsRec");
			if (actItem == null) {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = "未找到账号" + p_req9146.recAct + "的商户配置节点";
				retAts.writeRetDetail(tmpRetDetail);
				return retAts;
			}

			StringBuilder sbXml = new StringBuilder();
			sbXml.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
			sbXml.append("<MasMessage xmlns=\"http://www.99bill.com/mas_cnp_merchant_interface\">");
			sbXml.append("<version>1.0</version>");
			sbXml.append("<QryTxnMsgContent>");
			sbXml.append("<externalRefNumber>" + p_req9146.askNumber + "</externalRefNumber>");
			sbXml.append("<txnType>PUR</txnType>");
			sbXml.append("<merchantId>" + actItem.merchantId + "</merchantId>");
			sbXml.append("<terminalId>" + actItem.termId + "</terminalId>");
			sbXml.append("</QryTxnMsgContent>");
			sbXml.append("</MasMessage>");

			String queryUrl = bankFront.getUrl("smsRecQuery");
			this.WriteBankLogLn("查询服务地址：" + queryUrl);

			String reqXml = sbXml.toString();
			this.WriteBankLogStep2(reqXml);

			SendBankRespose smsResp = SmsPost.sendPost(queryUrl, actItem, reqXml, getCharset());

			this.WriteBankLogStep3(smsResp);

			if (smsResp.connState.length() == 0) {
				if (smsResp.retMessage.indexOf("<") >= 0) {
					XmlTextReader xmlReader = new XmlTextReader(smsResp.retMessage);
					tmpRetDetail.respCode = "0";
					tmpRetDetail.reqSeqID = xmlReader.getFirstText("/MasMessage/QryTxnMsgContent/externalRefNumber");
					tmpRetDetail.transAmt = xmlReader.getFirstText("/MasMessage/TxnMsgContent/amount");
					String externalRefNumber = xmlReader.getFirstText("/MasMessage/TxnMsgContent/externalRefNumber");
					if (StringHelper.hasAnyChar(externalRefNumber)) {
						tmpRetDetail.reqSeqID = externalRefNumber;
					}

					tmpRetDetail.outTransID = xmlReader.getFirstText("/MasMessage/TxnMsgContent/refNumber");

					/*
					 * <responseCode>KJ</responseCode> <responseTextMessage></responseTextMessage>
					 * <txnStatus>F</txnStatus>
					 */
					String responseCode = xmlReader.getFirstText("/MasMessage/TxnMsgContent/responseCode");
					String responseTextMessage = xmlReader
							.getFirstText("/MasMessage/TxnMsgContent/responseTextMessage");
					String voidFlag = xmlReader.getFirstText("/MasMessage/TxnMsgContent/voidFlag");
					String txnStatus = xmlReader.getFirstText("/MasMessage/TxnMsgContent/txnStatus");
					int countTxnMsgCo = xmlReader.countElement("/MasMessage/TxnMsgContent");
					if (StringHelper.hasAnyChar(responseCode)) {

						tmpRetDetail.transState = responseCode + "+" + voidFlag + "+" + txnStatus;
						tmpRetDetail.payInfoCode = responseCode;
						tmpRetDetail.respInfo = responseTextMessage;
					} else if (countTxnMsgCo == 0) {
						String errorCode = xmlReader.getFirstText("/MasMessage/ErrorMsgContent/errorCode");
						String errorMessage = xmlReader.getFirstText("/MasMessage/ErrorMsgContent/errorMessage");

						tmpRetDetail.payInfoCode = errorCode;
						if (errorMessage != null && errorMessage.toLowerCase().indexOf("no transaction") >= 0
								&& errorMessage.toLowerCase().indexOf("exists") > 0) {
							tmpRetDetail.transState = errorCode + "+No transaction exists";
							tmpRetDetail.payInfoCode = "No transaction exists";
						} else {
							tmpRetDetail.transState = errorCode;
						}
						tmpRetDetail.respInfo = errorMessage;
					} else {
						tmpRetDetail.respCode = "-1";
						tmpRetDetail.respInfo = "返回报文结构不符合预期";
					}
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = smsResp.retMessage;
				}
			} else {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = smsResp.retMessage;
			}

		} catch (Exception ex) {
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = ex.getMessage();
			tmpRetDetail.reqSeqID = p_req9146.askNumber;
			this.WriteBankLogLn(ex);
		}

		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}
}
